package com.livestocksolutions.intent;

import java.util.Arrays;
import java.util.Date;

import com.livestocksolutions.LivestockSolutions;
import com.livestocksolutions.Location;
import com.livestocksolutions.Observation;
import com.livestocksolutions.R;
import com.livestocksolutions.ui.ViewGroupMobArrayAdapter;
import com.livestocksolutions.ui.ViewLocationArrayAdapter;
import com.livestocksolutions.ui.ListObservationArrayAdapter;
import com.livestocksolutions.ui.ViewLocationPaddockArrayAdapter;
import com.livestocksolutions.ui.ViewObservationArrayAdapter;
import com.livestocksolutions.util.StringArrayParcelable;

import android.content.Intent;
import android.os.Bundle;
import android.view.ContextMenu;
import android.view.Menu;
import android.view.View;
import android.view.ContextMenu.ContextMenuInfo;
import android.widget.LinearLayout;
import android.widget.Toast;

/* -- Version History --
 *  1.0 : 05 August 2012 - Initial version. 
*  
 *  1.1 : 13 August 2012 - Created super class BaseActivity to hold all methods that are
 *                         standard across Activities
 *  
 *  1.2 : 09 September 2012 - Changed underlying structure to avoid using ListView for 
 *                         listed items that can be modifiable so that everything behaves
 *                         on screen rotation and upon the display of the virtual keyboard.
 */

/**
 * This class manages a Location object
 * @author Adam Parr
 * @version 1.2
 * 
 * @.modified 28 September 2012
 */
public class LocationActivity extends BaseActivity {
	public static final int LOCATIONVIEW 		 	= 0;
	/**
	 * Stores the reference to the XML layout template for each view
	 * @see #LOCATIONVIEW
	 */
	public static final Integer[] RESOURCEID = new Integer[]{
		R.layout.item
	};
	
	/**
	 * Location View that holds the data of the Location
	 */
	protected ViewLocationPaddockArrayAdapter locationView;
	/**
	 * Observation View that holds the Observations of the Location
	 */
	protected ListObservationArrayAdapter observations;
	
	/**
	 * Constructor
	 */
	public LocationActivity() {
		super(RESOURCEID);
	}
	
	protected LocationActivity(Integer[] resourceID){
		super(resourceID);
	}
	
    @Override
    public void onCreate(Bundle savedInstanceState) {
    	super.onCreate(savedInstanceState);
        
        if(stack.size()==0){
        	setContentView(RESOURCEID[LOCATIONVIEW]);
    		if(!built){
    			// Put the ID of this Location Object
	            id = id!=-1?id:getIntent().getExtras().getLong(ITEMID,-1);
    			Location l = LivestockSolutions.getLocationByID(id);
    			// Read initial state of the Location Object and add to locationType and observationValues
    			String[] locationType = new String[ViewLocationPaddockArrayAdapter.SIZE];
    			locationType[ViewLocationPaddockArrayAdapter.ID] 			= String.valueOf(l.getID());
    			locationType[ViewLocationPaddockArrayAdapter.NAME] 		= l.getName();
    			locationType[ViewLocationPaddockArrayAdapter.DESCRIPTION] 	= l.getDescription();
    			
    			Observation[] observationList = l.getObservations();
    			Arrays.sort(observationList, observationComparator);
	            String[][] observationValues = new String[observationList.length][];
	            for(int x=0; x<observationList.length; x++){
	            	String[] item = new String[ViewObservationArrayAdapter.SIZE];
	            	item[ViewObservationArrayAdapter.ID]=String.valueOf(observationList[x].getID());
	            	item[ViewObservationArrayAdapter.DATE]=String.valueOf(observationList[x].getDate().getTime());
	            	item[ViewObservationArrayAdapter.TYPE]=String.valueOf(observationList[x].getPriority());
	            	item[ViewObservationArrayAdapter.VALUE]=observationList[x].getComment();
	    			
	            	observationValues[x]=item;
	            }
				
    			locationView = new ViewLocationArrayAdapter(this, locationType);
    	    	observations = new ListObservationArrayAdapter(this, observationValues);

		    	setPage();
		    	drawObservations();
	            
				currentState.putInt(STATEID,LOCATIONVIEW);
	    		currentState.putBoolean("built",true);
    		}
    	}
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
    	// Show the menu for an Location Object
        getMenuInflater().inflate(R.menu.location_menu, menu);
        this.menu=menu;
        return true;
    }

    
    @Override
    public void onSaveInstanceState (Bundle outState) {
    	super.onSaveInstanceState (outState);
 
    	outState.putParcelable("locationType", new StringArrayParcelable().setStrings(locationView.get()));
    	outState.putParcelable("locationObservation", new StringArrayParcelable().setStrings(observations.get()));
    }
    
    @Override
    public void onRestoreInstanceState(Bundle inState) {
    	if(locationView ==null){
    		locationView = new ViewLocationArrayAdapter(this,((StringArrayParcelable)inState.getParcelable("locationType")).getStrings()[0]);
    	}
    		observations = new ListObservationArrayAdapter(this,((StringArrayParcelable)inState.getParcelable("locationObservation")).getStrings());
    	
    	super.onRestoreInstanceState (inState);
    }
    
    @Override
    public void onCreateContextMenu(ContextMenu menu, View view, ContextMenuInfo menuInfo) {
    	
    }
    
    @Override
    public boolean frameSelection(int frame) {
        switch (frame) {
        	case R.id.menu_add_observation:
        		// Add a blank observation, Start a new Observation
        		Intent locationIntent = new Intent(LocationActivity.this, ObservationActivity.class);
        		locationIntent.putExtra(ITEMID, -1);
        		locationIntent.putExtra("data",new String[]{});
        		startActivityForResult(locationIntent, NEW);
	        	//$FALL-THROUGH$
			case R.id.menu_observation:
        		showView(LOCATIONVIEW,currentState);
        		break;
        	case R.id.menu_save:
        		if(locationView.isValid()){
	        		edit = false;
	        		
	        		Location l = id==-1?new Location():LivestockSolutions.getLocationByID(id);
	        		l.setName(locationView.get()[0][ViewGroupMobArrayAdapter.NAME]);
	        		l.setDescription(locationView.get()[0][ViewGroupMobArrayAdapter.DESCRIPTION]);
	        		
	        		id=l.getID();
	        		if(LivestockSolutions.addLocation(l)){
	        			Toast.makeText(this,getResources().getString(R.string.message_saved,getResources().getString(R.string.location)),Toast.LENGTH_SHORT).show();
	        		}else{
	        			Toast.makeText(this,getResources().getString(R.string.message_errorSave,getResources().getString(R.string.location),getResources().getString(R.string.message_unknown)),Toast.LENGTH_SHORT).show();
	        		}
	        		
	        		built=false;
	        		onPrepareOptionsMenu(menu);
	        		showView(currentState.getInt(STATEID,LOCATIONVIEW),currentState);
	        		// Pop current view
	        		stack.pop();
	        		// Pop edit change
	        		stack.pop();
	        		break;
        		}
		        //$FALL-THROUGH$
			default:
	        	return super.frameSelection(frame);
        }
        return true;
    }
    
	@Override
	public boolean constructFrame(int view) {
		switch (view) {
			case LOCATIONVIEW:
				setContentView(RESOURCEID[LOCATIONVIEW]);
				setPage();
				drawObservations();
				break;
			default:
				return super.constructFrame(view);
		}
		return true;
	}
    
    @Override
    public void onActivityResult(int requestCode, int resultCode, Intent data){
    	if(resultCode == RESULT_OK){
    		Location l = LivestockSolutions.getLocationByID(id);
    		int index = data.getIntExtra(ITEMID, -1);
    		String[] returned = data.getStringArrayExtra("data");
	    	switch (requestCode){
		    	case EXISTING:
		    		// If id does not exist then there must be an error!
		    		if(index>-1){
			    		observations.replace(returned, index);
			    		drawObservations();
			    		Observation[] bovineObservationList = l.getObservations();
			    		Observation observation = null;
			    		for(Observation o : bovineObservationList){
			    			if(o.getID() == Long.parseLong(returned[ViewObservationArrayAdapter.ID])){
			    				observation = o;
			    				observation.setComment(returned[ViewObservationArrayAdapter.VALUE]);
			    				observation.setPriority(Integer.parseInt(returned[ViewObservationArrayAdapter.TYPE]));
			    				break;
			    			}
			    		}
			    		if(observation!=null){
			    			l.addObservation(observation);
			    			LivestockSolutions.addLocation(l);
			    		}
		    		}else{
		    			Toast.makeText(this, getResources().getString(R.string.message_errorSave,R.string.observation,R.string.message_unexpectedReturn), Toast.LENGTH_SHORT).show();
		    		}
		    		break;
		    	case NEW:
		    		observations.add(returned);
		    		index = observations.getCount()-1;
		    		drawObservations();
    				l.addObservation(new Observation(
						new Date(Long.parseLong(returned[ViewObservationArrayAdapter.DATE])),
						returned[ViewObservationArrayAdapter.VALUE],
						Integer.parseInt(returned[ViewObservationArrayAdapter.TYPE])
					));
    				LivestockSolutions.addLocation(l);
		    		break;
	    	}
    	}
    }
    
    /**
     * Set up the view to show the relevant content
     */
    protected void setPage(){
    	LinearLayout itemView = (LinearLayout) findViewById(R.id.listView);
    	if(edit){
			((ViewLocationArrayAdapter)locationView).setModifyLocation();
	    }else{
	    	((ViewLocationArrayAdapter)locationView).setViewLocation();
	    }
    	locationView.setRoot(itemView);
    	itemView.addView(locationView.getView(0,null, itemView),0);
    }
    
    /**
     * Draw the list of Observations.<br>
     * As these contain non-editable content, nothing can be in the middle of being altered.
     * So the whole list can be re-drawn to show any changes.
     */
    protected void drawObservations(){
    	setupListTitle(R.id.selectiveListTitle, R.layout.list_item_observation);
		
		LinearLayout view = (LinearLayout) findViewById(R.id.selectiveList);
		view.removeAllViews();
		final ListObservationArrayAdapter listObservation = observations;
		if(listObservation.getCount()>0){
			listObservation.setRoot(view);
			for(int x=0; x< listObservation.getCount(); x++){
				View v = listObservation.getView(x, null, view);
				v.setOnClickListener(new View.OnClickListener() {
					public void onClick(View v) {
						Intent intent = new Intent(LocationActivity.this, ObservationActivity.class);
						intent.putExtra("data",observations.getItem(v.getId()));
						intent.putExtra(ITEMID, v.getId());
						startActivityForResult(intent, EXISTING);
					}
				});
				view.addView(v,x);
			}
	    }else{
			view.addView(inflateLayout(R.layout.item_none,view));
		}
    }
}